﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DatabaseComponent;

public partial class start_examAR : System.Web.UI.Page
{
    List<string> lstCurrentAnswers
    {
        get
        {
            if (ViewState["lstCurrentAnswers"] == null)
            {
                ViewState["lstCurrentAnswers"] = System.Guid.NewGuid().ToString();

            }
            if (Session[ViewState["lstCurrentAnswers"].ToString()] == null)
                Session[ViewState["lstCurrentAnswers"].ToString()] = new List<string>();

            return Session[ViewState["lstCurrentAnswers"].ToString()] as List<string>;

        }
        set
        {
            if (ViewState["lstCurrentAnswers"] == null)
            {
                ViewState["lstCurrentAnswers"] = System.Guid.NewGuid().ToString();

            }

            Session[ViewState["lstCurrentAnswers"].ToString()] = value;
        }

    }

    List<Questions> lstCurrentQuestions
    {
        get
        {
            if (ViewState["lstCurrentQuestions"] == null)
            {
                ViewState["lstCurrentQuestions"] = System.Guid.NewGuid().ToString();

            }

            return Session[ViewState["lstCurrentQuestions"].ToString()] as List<Questions>;

        }
        set
        {
            if (ViewState["lstCurrentQuestions"] == null)
            {
                ViewState["lstCurrentQuestions"] = System.Guid.NewGuid().ToString();

            }

            Session[ViewState["lstCurrentQuestions"].ToString()] = value;
        }

    }



    RegisteredCourses objCurrentRegistered
    {
        get
        {
            if (ViewState["objCurrentRegistered"] == null)
            {
                ViewState["objCurrentRegistered"] = System.Guid.NewGuid().ToString();

            }


            return Session[ViewState["objCurrentRegistered"].ToString()] as RegisteredCourses;
        }
        set
        {
            if (ViewState["objCurrentRegistered"] == null)
            {
                ViewState["objCurrentRegistered"] = System.Guid.NewGuid().ToString();

            }


            Session[ViewState["objCurrentRegistered"].ToString()] = value;
        }
    }



    Exams objExams
    {
        get
        {
            if (ViewState["objExams"] == null)
            {
                ViewState["objExams"] = System.Guid.NewGuid().ToString();

            }

            if (Session[ViewState["objExams"].ToString()] == null)
            {
                return null;
            }

            return (Exams)Session[ViewState["objExams"].ToString()];



        }

        set
        {
            if (ViewState["objExams"] == null)
            {
                ViewState["objExams"] = System.Guid.NewGuid().ToString();

            }

            Session[ViewState["objExams"].ToString()] = value;


        }

    }


    protected void Page_Load(object sender, EventArgs e)
    {




        if (!Page.IsPostBack)
        {

            if (objExams == null)
            {

                checkSecurityAndCustomizePage();







            }


            bindAllControls();
        }


    }



    /// <summary>
    /// this function will bind all the controls of the page
    /// </summary>
    private void bindAllControls()
    {
        string [] lstIDs = objExams.ExamIDs.Split(",".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);

        string[] lstAnswers = objExams.Answers.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);


        

        grdQuestions.DataSource = lstCurrentQuestions;
        grdQuestions.DataBind();
       

        
    }

   



    /// <summary>
    /// this function will calculate if this persons succeeded or not.
    /// </summary>
    private void CalculateResult()
    {
       

        string[] lstAnswers = generateAnswersTrueOrFalse();


        


        double degree = 0;
        double AllDegree = 0;

        long i=0;
        foreach (Questions qs in lstCurrentQuestions)
        {
            AllDegree += qs.QuestionDegree;

            if (lstAnswers[(int)i] == "1")
                degree += qs.QuestionDegree;

            i++;

        }

        
        double percentage = degree * 100.0/AllDegree;
        
        bool isSucceed = true;
        if (percentage < objCurrentRegistered.objCourses.objCoursesDegree.Degree)
            isSucceed = false;


        objCurrentRegistered.CourseStatus = isSucceed ? 4 : ((long)CourseEnum.Waiting_exam);


        RegisteredCoursesDB objRegisteredCoursesDB = new RegisteredCoursesDB(ConnectionStrings.LMS);
        objRegisteredCoursesDB.Update(objCurrentRegistered);

        FinishedExamsDB objFinishedExamsDB = new FinishedExamsDB(ConnectionStrings.LMS);

        FinishedExams objFininshed = new FinishedExams();
        objFininshed.Degree = percentage;
        objFininshed.RegisteredCoursesID = objCurrentRegistered.ID;
        objFininshed.Answers = objExams.Answers;
        objFininshed.CurrentDate = DateTime.Now;
        objFininshed.ExamIDs = objExams.ExamIDs;
        objFinishedExamsDB.Insert(objFininshed);


        ExamsDB objExamsDB = new ExamsDB(ConnectionStrings.LMS);

        objExamsDB.Delete(objExams);


        GlobalVars.addLog(objCurrentRegistered.ID, isSucceed ? 4 : 3);
        if (isSucceed)
            GlobalVars.sendLogMail(objCurrentRegistered, objCurrentRegistered.objPersons, 4);

         pnlShowResult.Visible = true;
            lblResult.Visible = true;

            grdQuestions.Visible = false;


            if (isSucceed)
            {


                lblResult.ForeColor = System.Drawing.Color.Green;
                lblResult.Text = "مبروك<br />درجتك هي " + objFininshed.Degree.ToString("00.00") + " %";

            }
            else
            {
                lblResult.ForeColor = System.Drawing.Color.Red;
                lblResult.Text = "للاسف<br />لقد فشلت في اجتياز الاختبار ودرجتك هي : " + objFininshed.Degree.ToString("00.00") + " %";
            }

            if (isSucceed)
            {
                GlobalVars.refreshRegistered(objCurrentRegistered);

            }
            else
            {
                GlobalVars.CustomizeRegisterForFail(objCurrentRegistered);
            }


    }


    /// <summary>
    /// this function will generate an array having if the answer true or false
    /// </summary>
    /// <returns>the array returned</returns>
    private string[] generateAnswersTrueOrFalse()
    {

        List<string> lstRet = new List<string>();


        for (int i = 0; i < lstCurrentQuestions.Count; i++)
        {
            lstRet.Add(getTrueOrFalse(lstCurrentAnswers[i], lstCurrentQuestions[i]));
        }


        return lstRet.ToArray();
                
    }


    /// <summary>
    /// this function will get a "1" if the answers is true and a "0" if false
    /// </summary>
    /// <param name="strAnswer">the answers string</param>
    /// <param name="qtNew">the question to check its answer</param>
    /// <returns>a string containing "1" or "0"</returns>
    private string getTrueOrFalse(string strAnswer, Questions qtNew)
    {
        string[] strAnswerOne = strAnswer.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

        List<long> lstAnswers = new List<long>(from obj in strAnswerOne select long.Parse(obj)  );


        foreach (QuestionsAnswers qa in qtNew.lstQuestionsAnswers)
        {
            if (lstAnswers.Contains(qa.ID))
            {
                if (qa.IsAnswer)
                {
                    lstAnswers.Remove(qa.ID);

                }
                else
                {
                    return "0";
                }
            }
            else
            {

                if (qa.IsAnswer)
                {
                    return "0";
                }
            }


        }

        if (lstAnswers.Count == 0)
            return "1";

        else
            return "0";

    }

    /// <summary>
    /// this function will check the user previliges and user registered courses and customize page
    /// </summary>
    protected void checkSecurityAndCustomizePage()
    {
        Persons currentPerson = GlobalVars.getCurrentPerson();
        if (!currentPerson.lstAllRulesIDs.Contains((long)RulesEnum.Registered_courses_page))
        {
            Response.Redirect("loginAR.aspx");
            return;
        }


        
        if (Request["ID"] == null)
        {
            Response.Redirect("loginAR.aspx");
            return;
        }

        long CourseID = 0;
        if (!long.TryParse(Request["ID"].ToString(), out CourseID))
        {
            Response.Redirect("loginAR.aspx");
            return;

        }


        CoursesDB objCoursesDB = new CoursesDB(ConnectionStrings.LMS);

        List<Courses> lstCourses = objCoursesDB.getCoursesByID(CourseID);


        if (lstCourses.Count == 0)
        {
            Response.Redirect("loginAR.aspx");
            return;
        }



       


        if (!currentPerson.lstCourses.Contains(lstCourses[0]))
        {
            Response.Redirect("loginAR.aspx");
            return;
        }


        if (lstCourses[0].lstQuestions.Count == 0)
        {
            Response.Redirect("loginAR.aspx");
            return;
        }


        long RegisteredID = -1;

        foreach (RegisteredCourses rc in currentPerson.lstRegisteredCourses)
        {
            if (rc.CoursesID == lstCourses[0].ID)
            {

                RegisteredID = rc.ID;

                objCurrentRegistered = rc;

                
                break;


            }

        }



        ExamsDB objExamsDB = new ExamsDB(ConnectionStrings.LMS);
        List<Exams> lstExams = objExamsDB.getExamsByRegisteredCoursesID(RegisteredID);

        if (lstExams.Count == 0)
        {
            lstCurrentQuestions = GlobalVars.RandomizeList(lstCourses[0].lstQuestions);

            lstCurrentAnswers = new List<string>();

            foreach (Questions qt in lstCurrentQuestions)
            {
                lstCurrentAnswers.Add("-1");
            }

            objExams = new Exams();

            objExams.RegisteredCoursesID = RegisteredID;
            objExams.Answers = generateAnswersIDs (lstCurrentAnswers);

            objExams.ExamIDs = generateQuestionsIDs(lstCurrentQuestions);

            objExamsDB.Insert(objExams);

            GlobalVars.addLog(objCurrentRegistered.ID, 5);

        }
        else
        {
            objExams = lstExams[0];


            List<string> lstStringQuestions = new List<string>(objExams.ExamIDs.Split(",".ToCharArray(),StringSplitOptions.RemoveEmptyEntries));

            lstCurrentQuestions = new List<Questions>();

            foreach (string id in lstStringQuestions)
            {
                QuestionsDB qdb = new QuestionsDB(ConnectionStrings.LMS);

                List<Questions> lstTemp = qdb.getQuestionsByID(long.Parse(id));

                if (lstTemp.Count > 0)
                    lstCurrentQuestions.Add(lstTemp[0]);
                else
                    lstCurrentQuestions.Add(new Questions());



            }


            lstCurrentAnswers = getAnswersFromString(objExams.Answers);

        }


        
        
    }

    /// <summary>
    /// this function will get a list of string from answers string
    /// </summary>
    /// <param name="strAnswers">the answers string have ID's seperated by ,</param>
    /// <returns>a list of these answwers</returns>
    public  List<string> getAnswersFromString(string strAnswers)
    {
        List<string> lstRet = new List<string>(objExams.Answers.Split(",".ToCharArray(),StringSplitOptions.RemoveEmptyEntries));
        return lstRet;
    }




    /// <summary>
    /// this function will generate a string contains all questions ids in order to store it in exam
    /// </summary>
    /// <param name="lstCurrentQuestions">the questions ids to store</param>
    /// <returns>a string containing ids seperated by ,</returns>
    private string generateQuestionsIDs(List<Questions> lstCurrentQuestions)
    {
        string strRet = "";


        for (int i = 0; i < lstCurrentQuestions.Count; i++)
        {
            if (i == 0)
                strRet = lstCurrentQuestions[i].ID.ToString();
            else
                strRet = strRet + "," + lstCurrentQuestions[i].ID.ToString();

        }








        return strRet;
       
    }


    /// <summary>
    /// this function will generate a string contains all Answers ids in order to store it in exam the empty answers will be -1
    /// </summary>
    /// <param name="lstAnswers">the Answers ids to store</param>
    /// <returns>a string containing ids seperated by ,</returns>
    private string generateAnswersIDs(List<string> lstAnswers)
    {
        string strRet = "";


        for (int i = 0; i < lstAnswers.Count; i++)
        {
            if (i == 0)
                strRet = lstAnswers[i];
            else
                strRet = strRet + "," + lstAnswers[i];

        }








        return strRet;

    }





    protected void grdQuestions_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {

        getAnswersFromGridAndUpdate();


        grdQuestions.DataSource = lstCurrentQuestions;
        grdQuestions.PageIndex = e.NewPageIndex;
        grdQuestions.DataBind();

    }


    /// <summary>
    /// this function will go to all rows in grid and get answers and update objExam
    /// </summary>
    private void getAnswersFromGridAndUpdate()
    {
        for (int iIndex = 0; iIndex < grdQuestions.Rows.Count; iIndex++)
        {
            if (grdQuestions.Rows[iIndex].RowType == DataControlRowType.DataRow)
            {
                GridViewRow gr = grdQuestions.Rows[iIndex];


                examControlAR ec1 = (examControlAR)gr.FindControl("ec1");
                
                long lQuestionID = long.Parse(grdQuestions.DataKeys[gr.RowIndex]["ID"].ToString());
                
                int i = 0;
                for (i = 0; i < lstCurrentQuestions.Count; i++)
                {
                    if (lstCurrentQuestions[i].ID == lQuestionID)
                        break;
                }

                if (i < lstCurrentQuestions.Count)
                {
                    lstCurrentAnswers[i] = ec1.getAnswer();
                    if (lstCurrentAnswers[i] == "")
                        lstCurrentAnswers[i] = "-1";
                }


            }
        }


        ExamsDB objExamsDB = new ExamsDB(ConnectionStrings.LMS);
        objExams.Answers = generateAnswersIDs(lstCurrentAnswers);
        objExamsDB.Update(objExams);

    }


    protected void grdQuestions_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            examControlAR ec1 = (examControlAR)e.Row.FindControl("ec1");
            ec1.showButton = false;
            long lQuestionID = long.Parse(grdQuestions.DataKeys[e.Row.RowIndex]["ID"].ToString());
            ec1.set(lQuestionID);
            int i = 0;
            for (i = 0; i < lstCurrentQuestions.Count; i++)
            {
                if (lstCurrentQuestions[i].ID == lQuestionID)
                    break;
            }

            if (i < lstCurrentQuestions.Count)
            {
                string strAnswer = lstCurrentAnswers[i];
                ec1.setAnswer(strAnswer);
            }

            
        }
    }
    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        getAnswersFromGridAndUpdate();

        CalculateResult();

        btnSubmit.Visible = false;
    }


    protected void btnExit_Click(object sender, EventArgs e)
    {
        if (grdQuestions.Visible == true)
            getAnswersFromGridAndUpdate();

        Response.Redirect("./RegisteredCoursesAR.aspx");
    }
}